import { Component, OnInit, ElementRef, AfterViewInit } from '@angular/core';
import { FormControl, Validators, FormBuilder } from '@angular/forms';
import { timer } from 'rxjs';
import { map } from 'rxjs/operators';

@Component({
  templateUrl: './demo2.component.html',
})
export class Demo2Component implements OnInit, AfterViewInit {
  constructor(private fb: FormBuilder, private elementRef: ElementRef) {}
  syncCtrl;
  asyncCtrl;
  name;
  password;
  email;
  phone;
  userErrorTip = {
    required: 'Name cannot be empty.',
    maxlength: 'Length cannot exceed 5.',
  };
  nameInvalid;
  phoneInvalid;
  visible = {
    phone: false,
  };
  errorTips = {
    phone: '',
  };
  // 表单错误信息
  errorTipsMap = {
    phone: {
      required: 'Phone cannot be empty.',
      maxlength: 'Length cannot exceed 10.',
    },
  };
  ngOnInit() {
    // 自定义同步校验
    this.syncCtrl = new FormControl('', (input: FormControl) => {
      if (!/^1(3|4|5|6|7|8|9)\d{9}$/.test(input.value)) {
        return { phoneError: true };
      }

      return null;
    });

    // 自定义异步校验
    this.asyncCtrl = new FormControl('', [], (input: FormControl) => {
      return timer(500).pipe(
        map(res => {
          return { asyncError: true };
        })
      );
    });

    this.name = new FormControl('', [Validators.required, Validators.maxLength(5)]);
    this.password = new FormControl('', Validators.required);
    this.email = new FormControl('', Validators.required);
    this.phone = new FormControl('', [Validators.required, Validators.maxLength(10)]);

    this.name.markAsDirty();
    this.name.updateValueAndValidity();

    this.password.markAsDirty();
    this.password.updateValueAndValidity();

    this.email.markAsDirty();
    this.email.updateValueAndValidity();

    this.phone.markAsDirty();
    this.phone.updateValueAndValidity();

    this.phone.statusChanges.subscribe(() => {
      this.checkInvalid(this.phone, 'phone');
    });
  }
  ngAfterViewInit() {
    this.checkInvalid(this.phone, 'phone');
  }

  checkInvalid(control, controlName) {
    this.phoneInvalid = control.invalid && (control.dirty || control.touched);
    this.visible[controlName] = this.phoneInvalid;

    if (control.errors) {
      this.errorTips[controlName] = this.errorTipsMap[controlName][Object.keys(control.errors)[0]];
    }
  }

  focus() {
    this.checkInvalid(this.phone, 'phone');
  }
}
